#include "stdafx.h"
#include "../NetworkIOModelLib/NetworkIOModelLib.h"
#include <ppl.h>

#ifdef _DEBUG
#pragma comment(lib, "../Debug/NetworkIOModelLib.lib")
#else
#pragma comment(lib, "../Release/NetworkIOModelLib.lib")
#endif

const TCHAR* ServerIP = _T("10.10.10.1");
const WORD ServerPort = 10002;
const DWORD TryToConnectCount = 1000;
DWORD ConnectedCount = 0;
const DWORD TryToSendCount = 100;
DWORD TotalRecvedBytes = 0;

void DoNetworkTest(INetworkLib* pNetworkLib)
{
	pNetworkLib->Initialize(
		[&](SOCKET socket, DWORD error){
			InterlockedIncrement(&ConnectedCount);
			printf("[%d] OnConnect(%d) error(%d)\n", ConnectedCount, socket, error);	
			for(DWORD i = 0; i < TryToSendCount; ++i)
			{
				IStreamBuffer* pStreamBuffer = StreamBuffer::CreateComponent();
				pStreamBuffer->Write("helloworld", 10);
				pNetworkLib->Send(socket, *pStreamBuffer);
			}
			
	}	
	,	[&](SOCKET socket){ 
		printf("OnAccept(%d)\n", socket);		
	}
	,	[](SOCKET socket){ 
		printf("OnDisconnect(%d)\n", socket);	
	}
	,	[](SOCKET socket, IStreamBuffer* pStreamBuffer){ 
		InterlockedExchangeAdd(&TotalRecvedBytes, pStreamBuffer->GetLength());
		printf("OnRecv(%d) bytes(%d) totalBytes(%d)\n", socket, pStreamBuffer->GetLength(), TotalRecvedBytes); 
		pStreamBuffer->Release();
	}
	);

	Concurrency::parallel_for((DWORD)0, TryToConnectCount, [&](DWORD){
		pNetworkLib->Connect(ServerIP, ServerPort);
	});
	
	while(1)
	{
		SleepEx(INFINITE, true);
	}
	pNetworkLib->Release();
}

TEST(NetworkLib, BlockingModel)
{	
	DoNetworkTest(BlockingModelLib::CreateComponent());
}

TEST(NetworkLib, SelectModel)
{	
	DoNetworkTest(SelectModelLib::CreateComponent());
}

TEST(NetworkLib, WSAAsyncSelectModel)
{	
	DoNetworkTest(WSAAsyncSelectModelLib::CreateComponent());
}

TEST(NetworkLib, WSAEventSelectModel)
{	
	DoNetworkTest(WSAEventSelectModelLib::CreateComponent());
}

TEST(NetworkLib, OverlappedCompletionRoutineModel)
{	
	DoNetworkTest(OverlappedCompletionRoutineModelLib::CreateComponent());
}

TEST(NetworkLib, OverlappedIOCPModel)
{	
	DoNetworkTest(OverlappedIOCPModelLib::CreateComponent());
}